package GAME;
import java.awt.BorderLayout;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import javax.swing.SwingUtilities;

import TDATopFive.*;
import player.player;
import player.raptor;
import weaponrelated.bullet;
import planes.*;
import AI.*;
import TDALista.*;
import player.*;
import powerup.*;
/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class game extends javax.swing.JFrame implements Runnable {

	{
		//Set Look & Feel
		try {
			javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	protected game window;
	protected player jugador;
	protected PositionList<enemy> enemies;
	protected PositionList<bullet> enemybullets;
	protected PositionList<bullet> allybullets;
	protected bulletAI mentebullets;
	protected moverenemyAI mentemoverenemy;
	protected powerupAI mentepowerup;
	protected fondoAI fondoanimado;
	protected JButton exit;
	protected JButton botonraptor;
	protected JButton botonstealth;
	protected JPanel panelfondo;
	protected JPanel paneljuego;
	protected JLabel HP;
	protected JLabel points;
	protected int puntos;
	protected JLabel fondo;
	protected JLabel nuke[];
	protected TopFive<Integer,String> top;
	protected JTextField t;
	
	/**
	* Auto-generated main method to display this JFrame
	*/
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				game inst = new game();
				inst.setLocationRelativeTo(null);
				inst.setVisible(true);
			}
		});
	}
	public game() {
		super();
		initGUI();
	}

/**
 * Metodo que inicia los componentes graficos del juego.
 */
	private void initGUI() {
			window=this;
			
			
				
			{
				paneljuego=new JPanel();
				paneljuego.setBounds(0,0,400,600);
				this.getContentPane().add(paneljuego);
				paneljuego.setLayout(null);
				paneljuego.setOpaque(false);
				paneljuego.setBackground(new java.awt.Color(0,0,0));
			}
			{
				panelfondo=new JPanel();
				panelfondo.setBounds(0,0,400,600);
				this.getContentPane().add(panelfondo);
				panelfondo.setLayout(null);
				panelfondo.setOpaque(false);
				panelfondo.setBackground(new java.awt.Color(0,0,0));
			}
			
			{
				fondo=new JLabel();
				fondo.setBounds(0,0,400,600);
				fondo.setIcon(new ImageIcon(getClass().getClassLoader().getResource("resources/fondocielo.png")));
				this.getContentPane().add(fondo);
				
			}
		{
			botonraptor = new JButton();
			paneljuego.add(botonraptor);
			botonraptor.setIcon(new ImageIcon(getClass().getClassLoader().getResource("resources/elegirraptor.png")));
			botonraptor.setBounds(10, 103, 186, 139);
			botonraptor.setBackground(new java.awt.Color(192,192,192));
			botonraptor.addActionListener(new oyenteraptor());
			botonraptor.setFocusable(false);
		}
		{
			botonstealth = new JButton();
			paneljuego.add(botonstealth);
			botonstealth.setIcon(new ImageIcon(getClass().getClassLoader().getResource("resources/elegirstealth.png")));
			botonstealth.setBackground(new java.awt.Color(192,192,192));
			botonstealth.setBounds(202, 104, 186, 139);
			botonstealth.addActionListener(new oyentestealth());
			botonstealth.setFocusable(false);
		}

		this.setResizable(false);
		
		try {
			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
			getContentPane().setLayout(null);
			getContentPane().setBackground(new java.awt.Color(255,255,255));
			{
			}
			pack();
			this.setSize(400, 600);
		} catch (Exception e) {
		    //add your error handling code here
			e.printStackTrace();
		}
		
	}

/**
 * Metodo que define los hilos del juego y otros componentes graficos.
 */
	public void initgame(){
		Comparador c=new Comparador();
		top=new TopCinco<Integer,String>(c);
		this.cargarpuntajes();
		puntos=0;
		fondoanimado=new fondoAI(this);
		enemybullets=new DoubleLinkedList<bullet>();
		allybullets=new DoubleLinkedList<bullet>();
		enemies=new DoubleLinkedList<enemy>();
		mentebullets=new bulletAI(this);
		mentemoverenemy=new moverenemyAI(this);
		mentepowerup=new powerupAI(this);
		this.run();
		
		
		
		
		{
			exit = new JButton();
			paneljuego.add(exit);
			exit.setText("EXIT");
			exit.setBounds(325, 0, 63, 23);
			exit.setFocusable(false);
			exit.addActionListener(new oyenteexit());
		}

		{
			HP = new JLabel();
			paneljuego.add(HP);
			HP.setText(""+jugador.gethp());
			HP.setBounds(4, 532, 72, 25);
			HP.setFont(new java.awt.Font("Stencil Std",1,28));
		}	
		{
			points = new JLabel();
			paneljuego.add(points);
			points.setText("0");
			points.setBounds(303, 532, 100, 25);
			
			points.setFont(new java.awt.Font("Stencil Std",1,28));
		}
		{
			nuke=new JLabel[3];
			for(int i=0;i<nuke.length;i++){
				nuke[i]=new JLabel();
				paneljuego.add(nuke[i]);
				nuke[i].setIcon(new ImageIcon(getClass().getClassLoader().getResource("resources/nukerino.png")));
				nuke[i].setBounds((100+i*40), 532, 30, 30);
			}
			
		}
		

	}

/**
 * Metodo que inicia los hilos de ejecucion del juego y setea su prioridad.
 */
	public void run() {
		Thread threadjugador=new Thread(jugador);
		threadjugador.setPriority(10);
		threadjugador.start();
		levelone lvl=new levelone(this);
		lvl.start();
		lvl.setPriority(1);
		fondoanimado.setPriority(1);
		mentepowerup.setPriority(2);
		mentebullets.setPriority(9);
		mentemoverenemy.setPriority(8);
		mentemoverenemy.start();
		fondoanimado.start();
		mentebullets.start();
		mentepowerup.start();
		
	}

/**
 * Consulta que retorna la nave del jugador.
 * @return player retorna la nave del jugador.
 */
	public player getplayer(){
		return jugador;
		
	}

/**
 * Metodo que agrega una bala amiga al juego.
 * @param b bullet bala a ser insertada en el juego.
 */
	public void agregarbalaamiga(bullet b){
		this.getpanel().add(b);
		allybullets.addLast(b);
		
	}
	/**
	 * Metodo que agrega una bala enemiga al juego.
	 * @param b bullet bala a ser insertada en el juego.
	 */
	public void agregarbalaenemiga(bullet b){
		this.getpanel().add(b);
		enemybullets.addLast(b);
		
	}
	/**
	 * Metodo que agrega un powerup al juego.
	 * @param p powerup a ser insertado en el juego.
	 */
	public void insertpowerup(powerup p){
		mentepowerup.insertpowerup(p);
		
		
	}
	/**
	 * Metodo que agrega un mig al juego.
	 * @param m mig a ser insertado en el juego.
	 */
	public void insertmig(mig m){
		
		enemies.addLast(m);
		int x=(int)(Math.random()*5000+1)%this.getWidth();
		Point pos=new Point(x,-50);
		this.getpanel().add(m);
		m.setLocation(pos);
		
			
	}
	/**
	 * Metodo que agrega un boss al juego.
	 * @param b boss a ser insertado en el juego.
	 */
	public void insertboss(boss b){
		jugador.desactivarnukes();
		enemies.addLast(b);
		int x=(this.getWidth()/2-(b.getWidth()/2));
		Point pos=new Point(x,0-b.getHeight());
		this.getpanel().add(b);
		b.setLocation(pos);
		
	}
	/**
	 * Metodo que agrega un avion kamikaze al juego.
	 * @param k kamikaze a ser insertado en el juego.
	 */
	public void insertkamikaze(kamikaze k){
		enemies.addLast(k);
		int x=(int)(Math.random()*5000+1)%this.getWidth();
		Point pos=new Point(x,-50);
		this.getpanel().add(k);
		k.setLocation(pos);
		
	}
	/**
	 * Consulta que retorna el panel del fondo.
	 * @return JPanel panel del fondo.
	 */
	public JPanel getpanelfondo(){
		return panelfondo;
	}
	/**
	 * Metodo que agrega un avion harrier al juego.
	 * @param m harrier a ser insertado en el juego.
	 */
	public void insertharrier(harrier m){
		
		enemies.addLast(m);
		int x=(int)(Math.random()*5000+1)%this.getWidth();
		Point pos=new Point(x,-50);	
		m.setLocation(pos);
		this.getpanel().add(m);
		
	}
	/**
	 * Metodo que agrega un avion mirage al juego.
	 * @param m mirage a ser insertado en el juego.
	 */
	public void insertmirage(mirage m){
		enemies.addLast(m);
		int x=(int)((Math.random()*5000+1)%(this.getHeight()/2));
		Point pos=new Point(this.getWidth(),x);
		this.getpanel().add(m);		
		m.setLocation(pos);
		
		
			
	}
	/**
	 * Metodo que disminuye la cantidad de nukes visibles y elimina a los enemigos en pantalla.
	 */
	public void nukeit(){
		int cantnukes=jugador.getcantnukes();
		nuke[cantnukes-1].setVisible(false);
		this.killenemies();
	}
	/**
	 * Metodo que incremente la cantidad de nukes visibles.
	 */
	public void agregarnuke(){
		int cantnukes=jugador.getcantnukes();
		nuke[cantnukes-1].setVisible(true);
	}
	/**
	 * Metodo que actualiza la vida del jugador en pantalla.
	 */
	public void refreshhp(){
		
		HP.setText(""+jugador.gethp());
		
	}
	/**
	 * Metodo que elimina una bala aliada del juego.
	 * @param b Position<bullet> position que contiene la bala a ser eliminada del juego.
	 */
	public void  removeallybullet(Position<bullet> b){
		b.element().vanish();
		this.getpanel().remove(b.element());
		try {
			allybullets.remove(b);
		} catch (InvalidPositionException e) {}
	}
	/**
	 * Metodo que elimina una bala aliada del juego.
	 * @param b Position<bullet> position que contiene la bala a ser eliminada del juego.
	 */
	public void  removeenemybullet(Position<bullet> b){
		b.element().vanish();
		this.getpanel().remove(b.element());
		try {
			enemybullets.remove(b);
		} catch (InvalidPositionException e) {System.out.println("hola");}
	}
	/**
	 * Metodo que devuelve un iterable con las posiciones de la lista de las balas aliadas dentro del juego.
	 * @return Iterable<Position<bullet>> que posee las posiciones de la lista de las balas aliadas dentro del juego.
	 */
	public Iterable<Position<bullet>> getallybullets(){
		return allybullets.positions();
	}
	/**
	 * Metodo que devuelve un iterable con las posiciones de la lista de las balas enemigas dentro del juego.
	 * @return Iterable<Position<bullet>> que posee las posiciones de la lista de las balas enemigas dentro del juego.
	 */
	public Iterable<Position<bullet>> getenemybullets(){
		return enemybullets.positions();
	}
	/**
	 * Metodo que devuelve un iterable con las posiciones de la lista de los enemigos dentro del juego.
	 * @return Iterable<Position<Enemy>> que posee las posiciones de la lista de enemigos dentro del juego.
	 */
	public Iterable<Position<enemy>> getenemies(){
		return enemies.positions();
	}
	/**
	 * Metodo que elimina un enemigo del juego.
	 * @param b Position<Enemy> position que contiene el enemigo a ser eliminado del juego.
	 */
	public void eliminarenemigo(Position<enemy> p){
		
		puntos=puntos+p.element().getpoints();
		points.setText(""+puntos);
		try {
			enemies.remove(p);
		} catch (InvalidPositionException e) {}
	}
	/**
	 * Metodo que mata a todos los enemigos en pantalla.
	 * @param b Position<Enemy> position que contiene el enemigo a ser eliminado del juego.
	 */
	public void killenemies(){
		for(enemy e:enemies)
			e.kill();
		enemies=new DoubleLinkedList<enemy>();
	}
	/**
	 * Metodo que crea un jugador de tipo stealth.
	 */
	public void selecstealth(){
		{
			jugador = new stealth(this);
			paneljuego.add(jugador, "North");
			jugador.setBounds(171, 503, 25, 35);
		}
	}
	/**
	 * Metodo que crea un jugador de tipo raptor.
	 */
	public void selecraptor(){
		{
			jugador = new raptor(this);
			paneljuego.add(jugador, "North");
			jugador.setBounds(171, 503, 25, 35);
		}
	}
	/**
	 * Metodo que devuelve el panel principal del juego donde estan todas las naves y los disparos.
	 */
	public JPanel getpanel(){
		return paneljuego;
	}
	/**
	 * Metodo que carga los puntajes de un archivo "puntajes.txt" que se encuentra en la misma ruta del JAR a un TopCinco.
	 */
	public void cargarpuntajes(){
		int i=0;
		String nombre;
		String aux;
		FileReader punt;
		try {
			String path = "./puntaje.txt";
			FileInputStream fis = new FileInputStream(path);
			BufferedReader bf = new BufferedReader(new InputStreamReader(fis));
		
		boolean cond=true;
		while(cond){
			try {			
				nombre=bf.readLine();
				aux=bf.readLine();
				if(nombre!=null && aux!=null){										
							
				int p=Integer.parseInt(aux);
				top.insert(p,nombre);}
				else cond=false;
			} catch (IOException e) {}
		}
		
		} catch (FileNotFoundException e) {System.out.println("FILENOTFOUND");}
		
	}
	/**
	 * Metodo que se ejecuta cuando muere el jugador o termina el nivel, permite ingresar un nombre para guardar el puntaje y muestra los 5 mejores puntajes en la pantalla.
	 */
	public void endgame(){
		
		if(!jugador.isalive()){
			;
			this.cargarpuntajes();
			killenemies();
			paneljuego.removeAll();
			JLabel l=new JLabel("INSERT NAME:");
			l.setFont(new java.awt.Font("Stencil Std",1,12));
			l.setBounds(((this.getWidth()/2)-150), (this.getHeight()-100), 100, 50);
			t=new JTextField();
			t.setBounds(((this.getWidth()/2)-50), this.getHeight()-100,200, 50);
			paneljuego.add(l);
			paneljuego.add(t);
			repaint();
			t.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					String nombre;
					int p;
					String n=t.getText();
					top.insert(puntos, n);
					JLabel hs=new JLabel("HIGHSCORES:");
					hs.setFont(new java.awt.Font("Stencil Std",1,20));
					hs.setBounds((window.getWidth()/2-75),50,150,50);
					paneljuego.add(hs);
					for(int i=0;i<top.size();i++){
						Entry<Integer,String> ent=top.getpos(i);
						nombre=ent.getValue();					
						p=ent.getKey();
						JLabel aux=new JLabel(i+1+".   "+nombre+"   "+p);
						aux.setFont(new java.awt.Font("Stencil Std",1,20));
						aux.setBounds((window.getWidth()/2-150),100+50*i,300,50);
						paneljuego.add(aux);
						repaint();
						
					}
					window.guardarpuntajes();
				}
			});
			
			
		}
		
	}
	/**
	 * Metodo que guarda los 5 mejores puntajes del juego en un archivo "puntaje.txt" que se encuentra en la misma ruta del JAR, si no existe lo crea.
	 */
	public void guardarpuntajes(){
		File f=new File("./puntaje.txt");
		try {
			FileWriter fw=new FileWriter(f);
			BufferedWriter bf=new BufferedWriter(fw);
			bf.flush();
		for(int i=0;i<top.size();i++){
			
			bf.write(top.getpos(i).getValue());
			bf.newLine();
			bf.write(top.getpos(i).getKey().toString());	
			bf.newLine();
		}
		bf.close();
		} catch (IOException e) {}
		
		
	}
	public class oyenteexit implements ActionListener{
		public void actionPerformed(ActionEvent e){
			
			System.exit(0);
		}
	}

	public class oyenteraptor implements ActionListener{
		public void actionPerformed(ActionEvent e){
			window.selecraptor();
			botonraptor.setVisible(false);
			botonstealth.setVisible(false);
			window.repaint();
			window.initgame();
		}
	}
	public class oyentestealth implements ActionListener{
		public void actionPerformed(ActionEvent e){
			window.selecstealth();
			botonraptor.setVisible(false);
			botonstealth.setVisible(false);
			window.repaint();
			window.initgame();
		}
	}
	
	

}
